package dycaps

import (
	"crypto/sha256"
	"fmt"
	"log"
	"sync"
)

// DyCAPS implements the handoff protocol based on DyCAPS
type DyCAPS struct {
	// 复用现有组件
	rbc       RBCInterface
	mvba      MVBAInterface
	threshold ThresholdSigInterface
	
	// KZG相关（如果有KZG库则使用，否则使用占位实现）
	kzg       KZGInterface
	
	// 门限常量 - 使用t+l+1
	reduceMin int // t+l+1
	voteMin   int // 2t+1 或 t+l+1
	distMin   int // 2t+1 或 t+l+1
	
	// 状态管理
	mu        sync.RWMutex
	state     HandoffState
}

// HandoffState 表示handoff协议的状态
type HandoffState int

const (
	StateIdle HandoffState = iota
	StatePrepare
	StateShareReduce
	StateProactivize
	StateShareDist
	StateComplete
)

// Committee 委员会结构
type Committee struct {
	Members []string `json:"members"`
	T       int      `json:"t"`
	N       int      `json:"n"`
	L       int      `json:"l"` // 新增L参数
}

// HandoffParams 参数结构
type HandoffParams struct {
	KzgPP     []byte `json:"kzg_pp"`
	OldCommit []byte `json:"old_commit"`
}

// HandoffOutput 输出结构 - 保持与原ADKR兼容
type HandoffOutput struct {
	TPK         []byte            `json:"tpk"`
	PKVec       []byte            `json:"pk_vec"`
	ShareMap    map[string][]byte `json:"share_map"`
	Commitments []byte            `json:"commitments"`
}

// ReduceMsg 减少消息结构
type ReduceMsg struct {
	DealerID int      `json:"dealer_id"`
	CommitB  []byte   `json:"commit_b"`
	Points   []Point  `json:"points"`
	Witness  []byte   `json:"witness,omitempty"`
}

// Point 点结构
type Point struct {
	Index int    `json:"index"`
	Value []byte `json:"value"`
}

// DistMsg 分发消息结构
type DistMsg struct {
	MemberID int      `json:"member_id"`
	CommitB  []byte   `json:"commit_b"`
	Points   []Point  `json:"points"`
	Witness  []byte   `json:"witness,omitempty"`
}

// 接口定义
type RBCInterface interface {
	Broadcast(data []byte) error
	Receive() ([]byte, error)
}

type MVBAInterface interface {
	Propose(proposal []byte) error
	Decide() ([]byte, error)
}

type ThresholdSigInterface interface {
	Sign(data []byte) ([]byte, error)
	Verify(data []byte, signature []byte) bool
	Combine(signatures [][]byte) ([]byte, error)
}

type KZGInterface interface {
	Commit(coefficients []byte) ([]byte, error)
	CreateWitness(commitment []byte, index int, value []byte) ([]byte, error)
	VerifyEval(commitment []byte, index int, value []byte, witness []byte) bool
}

// 占位KZG实现
type PlaceholderKZG struct{}

func (k *PlaceholderKZG) Commit(coefficients []byte) ([]byte, error) {
	// 使用SHA256作为占位实现
	hash := sha256.Sum256(coefficients)
	return hash[:], nil
}

func (k *PlaceholderKZG) CreateWitness(commitment []byte, index int, value []byte) ([]byte, error) {
	// 占位实现：返回空见证
	return []byte{}, nil
}

func (k *PlaceholderKZG) VerifyEval(commitment []byte, index int, value []byte, witness []byte) bool {
	// 占位实现：总是返回true
	return true
}

// NewDyCAPS 创建新的DyCAPS实例
func NewDyCAPS(rbc RBCInterface, mvba MVBAInterface, threshold ThresholdSigInterface) *DyCAPS {
	return &DyCAPS{
		rbc:       rbc,
		mvba:      mvba,
		threshold: threshold,
		kzg:       &PlaceholderKZG{}, // 使用占位实现
		state:     StateIdle,
	}
}

// Handoff 执行DyCAPS handoff协议
func (d *DyCAPS) Handoff(oldCommittee, newCommittee Committee, params HandoffParams) (*HandoffOutput, error) {
	log.Printf("[DyCAPS] Starting handoff protocol")
	
	// 验证委员会参数
	if err := d.validateCommittees(oldCommittee, newCommittee); err != nil {
		return nil, fmt.Errorf("invalid committees: %v", err)
	}
	
	// 设置门限 - 使用t+l+1
	d.reduceMin = oldCommittee.T + oldCommittee.L + 1
	d.voteMin = newCommittee.T + newCommittee.L + 1
	d.distMin = newCommittee.T + newCommittee.L + 1
	
	log.Printf("[DyCAPS] Thresholds set: reduce=%d, vote=%d, dist=%d", 
		d.reduceMin, d.voteMin, d.distMin)
	
	// 执行四阶段协议
	if err := d.executeFourPhases(oldCommittee, newCommittee, params); err != nil {
		return nil, fmt.Errorf("handoff failed: %v", err)
	}
	
	// 生成输出
	output, err := d.generateOutput(newCommittee)
	if err != nil {
		return nil, fmt.Errorf("output generation failed: %v", err)
	}
	
	log.Printf("[DyCAPS] Handoff completed successfully")
	return output, nil
}

// validateCommittees 验证委员会参数
func (d *DyCAPS) validateCommittees(oldCommittee, newCommittee Committee) error {
	// 检查新委员会满足n >= 3t + 2l + 1
	if newCommittee.N < 3*newCommittee.T + 2*newCommittee.L + 1 {
		return fmt.Errorf("new committee does not satisfy n >= 3t + 2l + 1")
	}
	
	// 检查门限设置
	if d.reduceMin > oldCommittee.N {
		return fmt.Errorf("reduce threshold %d exceeds old committee size %d", d.reduceMin, oldCommittee.N)
	}
	
	if d.voteMin > newCommittee.N {
		return fmt.Errorf("vote threshold %d exceeds new committee size %d", d.voteMin, newCommittee.N)
	}
	
	return nil
}

// executeFourPhases 执行四阶段协议
func (d *DyCAPS) executeFourPhases(oldCommittee, newCommittee Committee, params HandoffParams) error {
	// Phase 1: Prepare
	if err := d.prepare(oldCommittee, newCommittee, params); err != nil {
		return fmt.Errorf("prepare phase failed: %v", err)
	}
	
	// Phase 2: ShareReduce
	if err := d.shareReduce(oldCommittee, newCommittee); err != nil {
		return fmt.Errorf("share reduce phase failed: %v", err)
	}
	
	// Phase 3: Proactivize
	if err := d.proactivize(newCommittee); err != nil {
		return fmt.Errorf("proactivize phase failed: %v", err)
	}
	
	// Phase 4: ShareDist
	if err := d.shareDist(newCommittee); err != nil {
		return fmt.Errorf("share dist phase failed: %v", err)
	}
	
	return nil
}

// prepare 执行Prepare阶段
func (d *DyCAPS) prepare(oldCommittee, newCommittee Committee, params HandoffParams) error {
	log.Printf("[DyCAPS] Phase 1: Prepare")
	d.setState(StatePrepare)
	
	// 广播旧承诺摘要
	oldCommitHash := d.hashCommitments(params.OldCommit)
	if err := d.rbc.Broadcast(oldCommitHash); err != nil {
		return fmt.Errorf("failed to broadcast old commitments: %v", err)
	}
	
	// 新委员会接收并缓存
	if err := d.cacheOldCommitments(oldCommitHash); err != nil {
		return fmt.Errorf("failed to cache old commitments: %v", err)
	}
	
	log.Printf("[DyCAPS] Prepare phase completed")
	return nil
}

// shareReduce 执行ShareReduce阶段
func (d *DyCAPS) shareReduce(oldCommittee, newCommittee Committee) error {
	log.Printf("[DyCAPS] Phase 2: ShareReduce")
	d.setState(StateShareReduce)
	
	// 收集reduce消息
	reduceMsgs := d.collectReduceMessages(oldCommittee, newCommittee)
	
	// 验证并内插
	for _, msg := range reduceMsgs {
		if d.verifyReduceMsg(msg) {
			if err := d.interpolateReducedShares(msg); err != nil {
				log.Printf("[DyCAPS] Failed to interpolate shares from dealer %d: %v", msg.DealerID, err)
			}
		}
	}
	
	log.Printf("[DyCAPS] ShareReduce phase completed, collected %d messages", len(reduceMsgs))
	return nil
}

// proactivize 执行Proactivize阶段
func (d *DyCAPS) proactivize(newCommittee Committee) error {
	log.Printf("[DyCAPS] Phase 3: Proactivize")
	d.setState(StateProactivize)
	
	// 生成刷新承诺
	commitQ, err := d.generateRefreshCommitment()
	if err != nil {
		return fmt.Errorf("failed to generate refresh commitment: %v", err)
	}
	
	// 广播承诺
	if err := d.rbc.Broadcast(commitQ); err != nil {
		return fmt.Errorf("failed to broadcast refresh commitment: %v", err)
	}
	
	// 收集阈值签名
	signatures, err := d.collectThresholdSignatures(commitQ)
	if err != nil {
		return fmt.Errorf("failed to collect threshold signatures: %v", err)
	}
	
	// MVBA选择有效集合
	selectedSet, err := d.mvbaSelect(signatures)
	if err != nil {
		return fmt.Errorf("failed to select via MVBA: %v", err)
	}
	
	log.Printf("[DyCAPS] Proactivize phase completed, selected %d commitments", len(selectedSet))
	return nil
}

// shareDist 执行ShareDist阶段
func (d *DyCAPS) shareDist(newCommittee Committee) error {
	log.Printf("[DyCAPS] Phase 4: ShareDist")
	d.setState(StateShareDist)
	
	// 生成最终份额
	freshShares, err := d.generateFreshShares(newCommittee)
	if err != nil {
		return fmt.Errorf("failed to generate fresh shares: %v", err)
	}
	
	// 分发份额
	for member, share := range freshShares {
		if err := d.distributeShare(member, share); err != nil {
			log.Printf("[DyCAPS] Failed to distribute share to member %s: %v", member, err)
		}
	}
	
	log.Printf("[DyCAPS] ShareDist phase completed, distributed %d shares", len(freshShares))
	return nil
}

// 辅助方法实现
func (d *DyCAPS) setState(state HandoffState) {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.state = state
}

func (d *DyCAPS) hashCommitments(commitments []byte) []byte {
	hash := sha256.Sum256(commitments)
	return hash[:]
}

func (d *DyCAPS) cacheOldCommitments(hash []byte) error {
	// 实现缓存逻辑
	log.Printf("[DyCAPS] Cached old commitments hash: %x", hash)
	return nil
}

func (d *DyCAPS) collectReduceMessages(oldCommittee, newCommittee Committee) []ReduceMsg {
	// 实现收集逻辑
	var msgs []ReduceMsg
	// 这里应该实现实际的收集逻辑
	return msgs
}

func (d *DyCAPS) verifyReduceMsg(msg ReduceMsg) bool {
	// 实现验证逻辑
	return true
}

func (d *DyCAPS) interpolateReducedShares(msg ReduceMsg) error {
	// 实现内插逻辑
	return nil
}

func (d *DyCAPS) generateRefreshCommitment() ([]byte, error) {
	// 实现生成逻辑
	commitment := []byte("refresh_commitment_placeholder")
	return commitment, nil
}

func (d *DyCAPS) collectThresholdSignatures(commitment []byte) ([][]byte, error) {
	// 实现收集逻辑
	var signatures [][]byte
	return signatures, nil
}

func (d *DyCAPS) mvbaSelect(signatures [][]byte) ([]byte, error) {
	// 实现MVBA选择逻辑
	selected := []byte("selected_set_placeholder")
	return selected, nil
}

func (d *DyCAPS) generateFreshShares(newCommittee Committee) (map[string][]byte, error) {
	// 实现生成逻辑
	shares := make(map[string][]byte)
	for _, member := range newCommittee.Members {
		shares[member] = []byte("fresh_share_" + member)
	}
	return shares, nil
}

func (d *DyCAPS) distributeShare(member string, share []byte) error {
	// 实现分发逻辑
	log.Printf("[DyCAPS] Distributed share to member %s", member)
	return nil
}

func (d *DyCAPS) generateOutput(newCommittee Committee) (*HandoffOutput, error) {
	// 生成输出结构
	output := &HandoffOutput{
		TPK:         []byte("threshold_public_key"),
		PKVec:       []byte("public_key_vector"),
		ShareMap:    make(map[string][]byte),
		Commitments: []byte("commitments_set"),
	}
	
	// 填充份额映射
	for _, member := range newCommittee.Members {
		output.ShareMap[member] = []byte("share_for_" + member)
	}
	
	return output, nil
}
